<?php


namespace app\controller\partner;


use app\BaseController;
use app\common\exception\ApiException;
use app\model\cart\CheckCartReportModel;
use app\model\cart\CheckCartReportRecordModel;
use app\model\cart\VerifyCartComplaintModel;
use app\model\coach\CoachRatioModel;
use app\model\config\CancelReasonModel;
use app\model\partner\EscortMenuOrderModel;
use app\model\partner\EscortMenuReserveOrderModel;
use app\model\partner\OrderLogModel;
use app\model\partner\PartnerBusyTimeModel;
use app\model\partner\UserPartnerModel;
use app\model\user\UserModel;
use app\service\config\ConfigService;
use app\service\config\DutyService;
use app\service\order\PartnerOrderService;
use app\service\utils\LockService;
use think\facade\Db;

class OrderController extends BaseController
{
    /**
     * 抢单列表
     * @return \think\response\Json
     */
    public function getOrderList()
    {
        try {
            // 1抢单 2待服务  3已完成
            $userId = $this->request->middleware('userId');
            $userInfo = $this->request->middleware('userInfo');
            $cityId = $userInfo['city'];
            $type = $this->request->param('type', 1, 'int');
            // 验车教练不显示
            $where = [];
            $where[] = ['city_id', '=', $cityId];
            if ($userInfo['user_type'] == 1) {
                $where[] = ['order_type', '=', 2];
            }
            if ($userInfo['user_type'] == 0) {
                $where[] = ['order_type', '=', 1];
            }
            if ($type == 1) {
                $where[] = ['status', '=', 1];
            } elseif ($type == 2) {
                $where[] = ['coach_user_id', '=', $userId];
                $where[] = ['status', 'in', [3, 7, 8]];
            } else {
                $where[] = ['coach_user_id', '=', $userId];
                $where[] = ['status', 'in', [4, 5]];
            }
            $list = EscortMenuReserveOrderModel::with(['source', 'user', 'menuOrder'])
                ->where($where)
                ->order(['id' => 'desc'])
                ->paginate(['list_rows' => $this->limit, 'page' => $this->page])
                ->toArray();
            foreach ($list['data'] as &$v) {
                if ($v['order_type'] == 2 && $userInfo['check_car_amount'] > 0) {
                    $menuOrderInfo = EscortMenuOrderModel::find($v['order_id']);
                    if ($menuOrderInfo['menu_id'] > 0) {
                        $v['coach_amount'] = intval($v['amount'] * $userInfo['check_car_amount'] / 100);
                    }
                }
                $remarkList = OrderLogModel::where('order_id', $v['id'])->column('reason');
                $v['remark'] = $v['remark'] . implode(';', $remarkList);
            }
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 拒接订单
     * @return \think\response\Json
     */
    public function refuseOrder()
    {
        Db::startTrans();
        $orderId = $this->request->param('order_id', 0, 'int');
        $userId = $this->request->middleware('userId');
        $key = 'order:refuse:%d:%d';
        $key = sprintf($key, $userId, $orderId);
        $lockService = new LockService($key);
        $uniqid = uniqid();
        try {
            if (!$lockService->acquireLockWithoutRetry($uniqid)) {
                throw new ApiException('请勿重复请求');
            }
            $reason = $this->request->param('reason', '', 'trim');

            $orderInfo = EscortMenuReserveOrderModel::find($orderId);
            if (!$orderInfo) {
                throw new ApiException('订单不存在');
            }
            if ($orderInfo['status'] != 3) {
                throw new ApiException('订单状态错误');
            }
            if ($orderInfo['coach_user_id'] != $userId) {
                throw new ApiException('非法请求');
            }
            if (!$reason) {
                throw new ApiException('请填写拒绝原因');
            }
            $orderInfo->status = EscortMenuReserveOrderModel::WAIT_ASSIGN_ORDER;
            $orderInfo->coach_user_id = 0;
            if ($orderInfo['reserve_type'] == 2) {
                $orderInfo->reserve_type = 1;
            }
            $orderInfo->save();

            // 订单日志
            $orderLogModel = new OrderLogModel();
            $orderLogModel->order_id = $orderId;
            $orderLogModel->coach_id = $userId;
            $orderLogModel->type = 2;
            $orderLogModel->title = '教练拒接';
            $orderLogModel->reason = $reason;
            $orderLogModel->save();

            // 教练排班取消
            DutyService::cancelBusyTime($userId, $orderInfo['reserve_time'], $orderInfo['duration']);
            Db::commit();
            $lockService->releaseLock($uniqid);
            return $this->success();
        } catch (\Exception $exception) {
            Db::rollback();
            $lockService->releaseLock($uniqid);
            return $this->error($exception);
        }
    }

    /**
     * 放入大厅
     * @return \think\response\Json
     */
    public function toPublic()
    {
        Db::startTrans();
        $orderId = $this->request->param('order_id', 0, 'int');
        $userId = $this->request->middleware('userId');
        $key = 'order:to_public:%d:%d';
        $key = sprintf($key, $userId, $orderId);
        $lockService = new LockService($key);
        $uniqid = uniqid();
        try {
            if (!$lockService->acquireLockWithoutRetry($uniqid)) {
                throw new ApiException('请勿重复请求');
            }

            $reason = $this->request->param('reason', '', 'trim');

            $orderInfo = EscortMenuReserveOrderModel::find($orderId);
            if (!$orderInfo) {
                throw new ApiException('订单不存在');
            }
            if ($orderInfo['status'] != 3) {
                throw new ApiException('订单状态错误');
            }
            if ($orderInfo['is_trial'] == 1) {
                throw new ApiException('体验课不能放回大厅');
            }
            if ($orderInfo['coach_user_id'] != $userId) {
                throw new ApiException('非法请求');
            }
            if (!$reason) {
                throw new ApiException('请填写拒绝原因');
            }
            $orderInfo->coach_user_id = 0;
            $orderInfo->status = EscortMenuReserveOrderModel::WAIT_ASSIGN_ORDER;
            $orderInfo->save();

            $orderLogModel = new OrderLogModel();
            $orderLogModel->order_id = $orderId;
            $orderLogModel->coach_id = $userId;
            $orderLogModel->type = 3;
            $orderLogModel->title = '教练放入大厅';
            $orderLogModel->reason = $reason;
            $orderLogModel->save();

            // 教练排班取消
            DutyService::cancelBusyTime($userId, $orderInfo['reserve_time'], $orderInfo['duration']);

            Db::commit();
            $lockService->releaseLock($uniqid);
            return $this->success();
        } catch (\Exception $exception) {
            Db::rollback();
            $lockService->releaseLock($uniqid);
            return $this->error($exception);
        }
    }

    /**
     * 接单
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function acceptOrder()
    {
        Db::startTrans();
        $orderId = $this->request->param('order_id', 0, 'int');
        $userId = $this->request->middleware('userId');
        $key = 'order:accept:%d';
        $key = sprintf($key, $orderId);
        $lockService = new LockService($key);
        $uniqid = uniqid();
        try {
            $userInfo = $this->request->middleware('userInfo');
            if ($userInfo['is_forbid'] == 1) {
                throw new ApiException('您已被禁止接单');
            }
            $orderInfo = EscortMenuReserveOrderModel::find($orderId);
            if (!$orderInfo) {
                throw new ApiException('订单不存在');
            }
//            $minRatio = ConfigService::getConfigValue('min_ratio');
//            if ($userInfo['ratio'] < $minRatio) {
//                throw new ApiException('您的化率低于' . $minRatio . ',请联系客服');
//            }
            $count = EscortMenuReserveOrderModel::where('coach_user_id', $userId)
                ->where('reserve_time', '<=', time())
                ->whereIn('status', [2, 3, 7, 8])
                ->count();
            $maxNum = ConfigService::getConfigValue('max_num');
            if ($count > $maxNum) {
                throw new ApiException('您的过期待服务体验单满' . $maxNum . '个，请联系客服');
            }
            $orderInfo->coach_user_id = $userId;
            $orderInfo->status = EscortMenuReserveOrderModel::WAIT_SERVICE;
            $orderInfo->accept_time = time();
            $orderInfo->save();

            // 教练确认接单 记入转化表
//            PartnerOrderService::setPartnerRatio($orderInfo['user_id'], $orderInfo['is_trial'], $userId);

            // 教练排班更新
            DutyService::setBusyTime($userId, $orderInfo['reserve_time'], $orderInfo['duration'], $orderId);
            Db::commit();
            $lockService->releaseLock($uniqid);
            return $this->success();
        } catch (\Exception $exception) {
            Db::rollback();
            $lockService->releaseLock($uniqid);
            $info = UserPartnerModel::find($userId);
            $info->is_forbid = 1;
            $info->remark = $exception->getMessage();
            $info->save();
            return $this->error($exception);
        }
    }

    /**
     * 验车报告题目
     * @return \think\response\Json
     */
    public function getCartReportList()
    {
        try {
            $userId = $this->request->middleware('userId');
            $list = CheckCartReportModel::select();
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 验车报告填写
     * @return \think\response\Json
     */
    public function setCartCheckReport()
    {
        try {
            $userId = $this->request->middleware('userId');
            $orderId = $this->request->param('order_id', 0, 'int');
            $record = $this->request->param('record', '', 'trim');
            $intro = $this->request->param('remark', '', 'trim');

            if (!is_array($record)) {
                throw new ApiException('请填写验车报告');
            }
            CheckCartReportRecordModel::where('order_id', $orderId)->delete();

            $dataAll = [];
            foreach ($record as $k => $value) {
                $titleId = $value['title_id'] ?? 0;
                $result = $value['result'] ?? 0;
                $remark = $value['remark'] ?? '';
                $img = $value['img'] ?? '';
                $title = CheckCartReportModel::where('id', $titleId)->value('title', '');
                if (!$title) {
                    continue;
                }
                $dataAll[$k] = [
                    'user_id' => $userId,
                    'order_id' => $orderId,
                    'title_id' => $titleId,
                    'title' => $title,
                    'result' => $result,
                    'img' => $img,
                    'remark' => $remark,
                    'intro' => $intro,
                ];
            }

            $checkCartReportRecordModel = new CheckCartReportRecordModel();
            $checkCartReportRecordModel->saveAll($dataAll);
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 评价
     * @return \think\response\Json
     */
    public function evalOrder()
    {
        Db::startTrans();
        try {
            $userId = $this->request->middleware('userId');
            $orderId = $this->request->param('order_id', 0, 'int');
            $eva = $this->request->param('eva', '', 'trim');

            $orderInfo = EscortMenuReserveOrderModel::find($orderId);
            if (!$orderInfo) {
                throw new ApiException('订单不存在');
            }

            $orderInfo->eval = $eva;
            $orderInfo->status = EscortMenuReserveOrderModel::COMPLETE;
            $orderInfo->save();
            Db::commit();
            return $this->success();
        } catch (\Exception $exception) {
            Db::rollback();
            return $this->error($exception);
        }
    }

    /**
     * 取消原因列表
     * @return \think\response\Json
     */
    public function getReasonList()
    {
        try {
            $type = $this->request->param('type', 0, 'int');
            $list = CancelReasonModel::where('type', $type)->select();
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }
}